#include "simulation_vector.h"

using namespace std;

namespace fuh{



    //直接实现反向迭代器
    template<class T, class Ref, class Ptr>
	struct Reverse_iterator
	{
        public:
        typedef Reverse_iterator<T, Ref, Ptr> self;
        Reverse_iterator()
        :_it(nullptr)
        {

        }
        Reverse_iterator(T* ptr)
        :_it(ptr)
        {

        }
        Ref operator*()
        {
            return *_it;
        }
        Ptr operator->()const
        {
            return _it;
        }
        self& operator--()//前置
        {
            _it++;
            return *this;
        }
        self operator--(int)//后置
        {
            _it++;
            return Reverse_iterator(_it-1);
        }
        self& operator++()
        {
            _it--;
            return *this;
        }
        self operator++(int)//后置
        {
            _it--;
            return Reverse_iterator(_it+1);
        }
        bool operator!=(const self& it_2)
        {
            return _it != it_2._it;
        }
        bool operator==(const self & it_2)
        {
            return _it == it_2._it;
        }
		T* _it;
	};

    
    //利用正向迭代器实现的反向迭代器
    template <class iterator,class Ref, class Ptr>
    class ReverseIterator{
        public:
        typedef ReverseIterator<iterator,Ref,Ptr> self;
        ReverseIterator(iterator it):_it(it){}

        self& operator++(){
            _it--;
            return *this;
        }
        self& operator--(){
            _it++;
            return *this;
        }
        self operator++(int){
            self tmp = *this;
            _it--;
            return tmp;
        }
        self operator--(int){
            self tmp = *this;
            _it++;
            return tmp;
        }
        bool operator==(const self& rhs){
            return _it == rhs._it;
        }
        bool operator!=(const self& rhs){
            return _it != rhs._it;
        }
        Ref operator*(){
            return *_it;
        }
        Ptr operator->(){
            return _it.operator->();//这里不能直接调用·
        }
        private:
        iterator _it;
    } ;

    template <class T>
    class vector
    {
        public:
            typedef T* iterator;
            typedef const T* const_iterator;
            typedef Reverse_iterator<T, T&, T*> reverse_iterator;
            typedef Reverse_iterator<T, const T&, const T*> const_reverse_iterator;
            typedef ReverseIterator<iterator, T&, T*> Reverse_iterator_byIterator;
            typedef ReverseIterator<const iterator, const T&, const T*> const_Reverse_iterator_byIterator;

            //对应直接实现的迭代器
            // reverse_iterator rbegin(){
            //     return _finish-1;
            // }
            // reverse_iterator rend(){
            //     return _start-1;
            // }
            // const_reverse_iterator rbegin()const
            // {
            //     return _finish-1;
            // }
            // const_reverse_iterator rend()const
            // {
            //     return _start-1;
            // }


            Reverse_iterator_byIterator rbegin()
            {
                return Reverse_iterator_byIterator(end()-1);//这里是个临时常亮不可--
            }
            Reverse_iterator_byIterator rend()
            {
                return Reverse_iterator_byIterator(begin()-1);
            }
            const_Reverse_iterator_byIterator rbegin() const
            {
                return const_Reverse_iterator_byIterator(end()-1);
            }
            const_Reverse_iterator_byIterator rend() const
            {
                return const_Reverse_iterator_byIterator(begin()-1);
            } 

            iterator begin(){
                return _start;
            }
            iterator end(){
                return _finish;
            }
            const_iterator begin()const
            {
                return _start;
            }
            const_iterator end()const
            {
                return _finish;
            }
            vector()
            :_start(nullptr)
            ,_finish(nullptr)
            ,_endOfStorage(nullptr)
            {

            }
            template <class Inputiterator>
            vector(Inputiterator first,Inputiterator end)
            :_start(nullptr)
            ,_finish(nullptr)
            ,_endOfStorage(nullptr)
            {
                while(first<end)
                {
                    push_back(*first++);
                }
            }
            vector(const vector<T>& v)
            :_start(nullptr)
            ,_finish(nullptr)
            ,_endOfStorage(nullptr)
            {
                vector<T> tmp(v.begin(),v.end());
                swap(tmp);
            }
            vector(size_t n,const T& val = T())
            :_start(nullptr)
            ,_finish(nullptr)
            ,_endOfStorage(nullptr)
            {
                while(size()<n)
                {
                    push_back(val);
                }
            }
            vector(const initializer_list<T>& Ini)
            {
                reserve(Ini.size());
                for(const auto& num:Ini)
                {
                    push_back(num);
                }
            }
            vector(int n,const T& val = T())
            :_start(nullptr)
            ,_finish(nullptr)
            ,_endOfStorage(nullptr)
            {
                while(size()<n)
                {
                    push_back(val);
                }
            }
            ~vector()
            {
                if(_start)
                delete[] _start;
                _start = nullptr;
            }
            void swap(vector<T>& v){
                iterator t= _start;
                _start = v._start;
                v._start = t;
                t= _finish;
                _finish = v._finish;
                v._finish = t;
                t= _endOfStorage;
                _endOfStorage = v._endOfStorage;
                v._endOfStorage = t;
            }
            vector& operator=(const vector<T>& v)
            {
                vector tmp(v.begin(),v.end());
                swap(tmp,*this);
                return *this;
            }
            void push_back(const T& x)
            {
                if(_finish == _endOfStorage)
                {
                    size_t _capacity = capacity() == 0? 4:capacity()*2;
                    reserve(_capacity);
                }
                *_finish++ = x;
            }
            T& operator[](size_t pos)
            {
                assert(pos < size());
                return *(pos+_start);
            }
            const T& operator[](size_t pos)const
            {
                assert(pos < size());
                return *(pos+_start);
            }
            size_t capacity()const
            {
                return _endOfStorage - _start;
            }
            size_t size()const
            {
                return _finish - _start;
            }
            void reserve(size_t n)
            {
                if(n>capacity())
                {
                    size_t _capacity = n;
                    T* tmp = new T[_capacity];
                    int _size = size();
                    if(_start)
                    { 
                        copy(tmp,_start,_finish -_start);
                        delete[]_start;
                    }
                    _start = tmp;
                    _finish = _start+_size;
                    _endOfStorage = _start +_capacity;
                }
            }
            void copy(iterator dest,const  iterator& sor,size_t n)
            {
                for(int i = 0;i<n;i++)
                {
                    dest[i] = sor[i];
                }
            }
            void resize(size_t n,const T& val = T())//内置类型也可以有构造
            {
                if(n<=size())
                {
                    _finish = _start +n;
                    return ;
                }
                else
                {
                    while(size()<n)
                    {
                        push_back(val);
                    }
                }
            }
            iterator insert(iterator pos,const T& val = T())//迭代器失效，为什么会失效，因为底层扩容导致指针位置改变
            //指针位置改变了，原迭代器指针就会失效
            {
                
                assert(pos<_finish && pos>=_start);
                if(size()+1>capacity())
                {
                    int position = pos - _start;
                    reserve(capacity()*2);
                    pos = _start + position;
                }
                
                _finish += 1;
                iterator end = _finish -1;
                while(end!=pos)
                {
                    *end = *(end-1);
                    end--;
                }
                *pos = val;
                return pos;
            }
            
            iterator insert(iterator pos,iterator input_start,iterator input_finish)
            {
                assert(pos<_finish && pos>=_start);
                if(size()+input_finish-input_start >capacity())
                {
                    int position = pos - _start;
                    reserve(size()+input_finish-input_start);
                    pos = _start + position;
                }
                iterator tmp = pos;
                size_t sz = input_finish-input_start;
                _finish+= sz;
                iterator end = _finish-1;
                while(end -sz+1!=pos)
                {
                    *end = *(end-sz);
                    end--;
                }
                while(input_start != input_finish)
                {
                    *pos++ = *input_start++;
                }
                return tmp;
            }
            iterator erase(iterator pos)
            {
                iterator tmp = pos;
                assert(pos>=_start && pos< _finish);
                while(pos+1<_finish)
                {
                    *pos = (*pos+1);
                    pos++;
                }
                _finish --;
                return tmp+1>_finish?_finish : tmp+1;
                
            }
            iterator erase(iterator first,iterator end)
            {
                assert(first>=_start && first< _finish);
                assert(end>=first && end< _finish);
                iterator tmp =first;
                int n = end - first +1;
                while(first+n<_finish)
                {
                    *first = (*first+n);
                    first ++;
                }
                _finish -= n ;
                return tmp+n>_finish?_finish : tmp+n;
            }
            void print()const
            {
                for(int i=0;i<_finish - _start;i++)
                {
                    cout<<(*this)[i]<<endl;
                }
                cout<<endl;
            }
        private:
            iterator _start;
            iterator _finish;
            iterator _endOfStorage;
    };
    void print()
    {

    }
    void Test_1()
    {
        vector<int> arr;
        arr.push_back(1);
        arr.push_back(2);
        arr.push_back(3);
        arr.push_back(4);
        for(int i=0;i<arr.size();i++)
        {
            cout<<arr[i]<<' ';
        }
        cout << endl;
        vector<int>::iterator it = arr.begin();
        for(;it!= arr.end();it++)
        {
            cout<<*it<<' ';
        }
        return;
    }
    void Test_2()//迭代器插入扩容和失效。
    {
        vector<double> arr(5,1.2);
        vector<double> rr(1,9.9);
        // arr.insert(arr.begin(),2.2);
        rr.insert(rr.end()-1,arr.begin(),arr.end());
        for(int i=0;i<rr.size();i++)
        {
            rr[i] = i+0.1;
        }
        rr.erase(rr.begin()+1,rr.end()-2);
        for(int i=0;i<rr.size();i++)
        {
            cout<< rr[i]<<' ';
        }
        cout << endl;
        return ;
    }
    void Test_3()
    {
        vector<string> s1(1,"111");
        vector<string> s2(s1);
        vector<string> s3(s1.begin(),s1.end());
        s2.push_back("222");
        s3.push_back("333");
        s1.print();
        s2.print();
        s3.print();
    }
    void Test_4()
    {
        vector<int> arr;
        arr.push_back(1);
        arr.push_back(2);
        arr.push_back(3);
        arr.push_back(4);
        auto it = arr.rbegin();
        while(it!= arr.rend())
        {
            cout<< *it++<<' ';
        }
        cout<<endl;
    }

};